package com.squirrel.common.shiro;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.squirrel.common.exception.BaseException;
import com.squirrel.common.response.code.CodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @Description JwtFilter shiro的过滤器
 * @Author 关远键
 * @Version v1.0.0
 * @Date 2021/12/13 10:46
 */
@Slf4j
public class JwtFilter extends AccessControlFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // GET和OPTIONS请求全部放行
        if (request.getMethod().equals("GET")) {
            return true;
        }
        if (request.getMethod().equals("OPTIONS")) {
            return true;
        }

        String url = request.getRequestURL().toString();
        // 截取请求路径的一部分
        // 如：localhost:8080/api/user/modify
        // 截取：/user/modify
        String str = url.substring(url.lastIndexOf(":") + 9);

        log.info("拦截请求路径：{}", str);
        // 登录注册放行
        if (str.startsWith("/user/") && !str.contains("modify")) {
            return true;
        }

        String token = request.getHeader("JWT");
        log.info("JWT:" + token);

        if (StringUtils.isBlank(token)) {
            log.info("过滤器拦截到请求：{}，拦截原因：用户未登录", url);
            throw new BaseException(CodeEnum.NO_AUTHORITY);
        }

        JwtToken jwtToken = new JwtToken(token);
        try {
            getSubject(servletRequest, servletResponse).login(jwtToken);
        } catch (Exception e) {
            return false;
        }

        return true;
    }
}
